<script setup lang="tsx">
import { Sender } from "ant-design-x-vue";
import { Welcome } from "ant-design-x-vue";
import {
  Flex,
  App,
  Card,
  ConfigProvider,
  Space,
  theme,
  message as messageApi,
  Typography,
  Select,
  Drawer,
  Button as AButton,
  Popconfirm,
  List,
  Spin,
  Collapse,
  Tag
} from "ant-design-vue";
import {
  ref,
  onMounted,
  onUnmounted,
  Fragment,
  computed,
  watchEffect,
  nextTick,
  Transition
} from "vue";
import { Prompts, BubbleList, Attachments } from "ant-design-x-vue";
import {
  UserOutlined,
  CommentOutlined,
  CloudUploadOutlined,
  ScanOutlined,
  PlusOutlined,
  HistoryOutlined,
  DeleteOutlined,
  CopyOutlined,
  SmileOutlined,
  FrownOutlined,
  SyncOutlined,
  CloseOutlined,
  UpOutlined,
  DownOutlined
} from "@ant-design/icons-vue";
import type {
  BubbleListProps,
  BubbleProps,
  PromptsProps
} from "ant-design-x-vue";
import { Button } from "ant-design-vue";
// 导入AI API
import { fetchAIStreamData } from "@/api/ai";
import {
  getAllModels,
  getSessionIdsAndLastData,
  createNewSession,
  getSessionContent
} from "@/api/index";
// 导入文档解析库
import mammoth from "mammoth";
import * as XLSX from "xlsx";
// 导入Markdown解析库
import MarkdownIt from "markdown-it";
// 导入KaTeX插件
import markdownItKatex from "markdown-it-katex";
// 导入KaTeX样式
import "katex/dist/katex.min.css";
// 导入路由
import { useRouter } from "vue-router";

// 定义消息接口
interface Message {
  key: number;
  role: "ai" | "user";
  content: string;
  footer?: any; // 添加footer属性，可以是任何类型
}

// 文件接口定义
interface UploadedFile {
  uid: string;
  name: string;
  size: number;
  type?: string;
  status?: "uploading" | "done" | "error" | "removed";
  content?: string;
  thumbUrl?: string;
  url?: string;
}

// 会话历史接口
interface Conversation {
  conversationId: string;
  lastUserInput: string;
  lastAiOutput: string;
  lastMessageTime: string;
}

// 会话消息记录接口
interface ConversationRecord {
  id: string;
  conversationId: string;
  userInput: string;
  aiOutput: string;
  createTime: string;
  useModel: string;
}

const messages = ref<Message[]>([]);
const loading = ref<boolean>(false);
// 添加上传文件列表
const uploadedFiles = ref<UploadedFile[]>([]);
// 当前解析的文件内容
const parsedFileContent = ref<string>("");

// 会话历史相关状态
const historyDrawerVisible = ref(false);
const conversationHistory = ref<Conversation[]>([]);
const currentConversationId = ref<string>("");
const loadingHistory = ref(false);

// 添加设备检测变量
const isPC = ref(true);

// 水印信息
const watermarkText = ref("学号姓名");
const watermarkDiv = ref<HTMLDivElement | null>(null);

// 添加用户头像和用户名引用
const userAvatar = ref<string>("");
const userName = ref<string>("");

// 创建markdown-it实例
const md = new MarkdownIt({
  html: true,
  breaks: true,
  linkify: true,
  typographer: true
});

// 使用KaTeX插件
md.use(markdownItKatex);

// 自定义Markdown渲染函数
const renderMarkdown: BubbleProps["messageRender"] = (content: string) => {
  try {
    // 检查是否包含思维链标签
    if (content && content.includes("<think>")) {
      // 提取思维链内容
      const thinkPattern = /<think>([\s\S]*?)<\/think>/g;
      const matches = [...content.matchAll(thinkPattern)];

      // 创建思维链和普通内容分离的DOM结构
      if (matches.length > 0) {
        // 替换所有思维链内容为空白，得到普通内容
        let normalContent = content;
        matches.forEach(match => {
          normalContent = normalContent.replace(match[0], "");
        });

        // 渲染普通内容
        const renderedNormalContent = md.render(normalContent.trim() || "");

        // 创建最终的组件结构
        return (
          <Typography>
            {matches.map((match, index) => (
              <Collapse
                ghost
                expandIconPosition="end"
                key={`think-${index}`}
                class="think-collapse"
              >
                <Collapse.Panel
                  key="1"
                  header={<span class="think-header">思维链展示</span>}
                >
                  <div
                    class="think-content markdown-body"
                    innerHTML={md.render(match[1] || "")}
                  ></div>
                </Collapse.Panel>
              </Collapse>
            ))}
            <div class="markdown-body" innerHTML={renderedNormalContent}></div>
          </Typography>
        );
      }
    }

    // 没有思维链标签，正常渲染
    const renderedContent = md.render(content || "");
    return (
      <Typography>
        <div class="markdown-body" innerHTML={renderedContent}></div>
      </Typography>
    );
  } catch (error) {
    console.error("Markdown渲染错误:", error);
    return (
      <Typography>
        <div>{content}</div>
      </Typography>
    );
  }
};

// 获取用户信息并设置水印文本
const getUserInfo = () => {
  try {
    const userInfoStr = localStorage.getItem("user-info");
    if (userInfoStr) {
      const userInfo = JSON.parse(userInfoStr);

      // 设置用户头像
      if (userInfo.avatar) {
        userAvatar.value = userInfo.avatar;
      }

      // 设置用户名
      if (userInfo.username && userInfo.nickname) {
        userName.value = `${userInfo.nickname}`;
        watermarkText.value = `${userInfo.username} ${userInfo.nickname}`;
      } else if (userInfo.username) {
        userName.value = userInfo.username;
        watermarkText.value = userInfo.username;
      } else if (userInfo.nickname) {
        userName.value = userInfo.nickname;
        watermarkText.value = userInfo.nickname;
      }
    }
  } catch (error) {
    console.error("获取用户信息失败:", error);
  }
};

// 创建水印
const createWatermark = () => {
  if (!watermarkDiv.value) return;

  const canvas = document.createElement("canvas");
  const ctx = canvas.getContext("2d");
  if (!ctx) return;

  // 设置画布大小
  canvas.width = 300;
  canvas.height = 150;

  // 设置文字样式
  ctx.font = `16px Arial`;
  ctx.fillStyle = `rgba(220, 220, 220, 0.35)`;
  ctx.textAlign = "center";
  ctx.textBaseline = "middle";

  // 旋转文字
  ctx.translate(150, 75);
  ctx.rotate(-Math.PI / 6);
  ctx.fillText(watermarkText.value, 0, 0);

  // 将水印设置为背景
  watermarkDiv.value.style.backgroundImage = `url(${canvas.toDataURL()})`;
};

// 渲染标题函数
const renderTitle = (icon: any, title: string) => (
  <Space align="start">
    {icon}
    <span>{title}</span>
  </Space>
);

// 处理Prompts项点击事件
const handlePromptsItemClick = (info: any) => {
  console.log(`您点击了提示: ${info.data.key}`);
  // 如果是子项，获取描述文本并发送
  if (info.data.description) {
    sendMessage(info.data.description);
  }
};

// 添加复制文本到剪贴板的函数
const copyToClipboard = (text: string) => {
  if (navigator.clipboard) {
    navigator.clipboard
      .writeText(text)
      .then(() => {
        messageApi.success("已复制到剪贴板");
      })
      .catch(() => {
        messageApi.error("复制失败，请手动复制");
      });
  } else {
    // 兼容旧浏览器
    const textArea = document.createElement("textarea");
    textArea.value = text;
    document.body.appendChild(textArea);
    textArea.select();
    try {
      document.execCommand("copy");
      messageApi.success("已复制到剪贴板");
    } catch (err) {
      messageApi.error("复制失败，请手动复制");
    }
    document.body.removeChild(textArea);
  }
};

// 添加反馈处理函数
const handleFeedback = (
  type: "like" | "dislike",
  content: string,
  key: number
) => {
  console.log(`用户对消息 ${key} 的反馈: ${type}`, content);
  messageApi.success(`感谢您的${type === "like" ? "好评" : "反馈"}！`);
  // 这里可以添加发送反馈到后端的逻辑
};

// 添加重新生成处理函数
const handleRegenerate = (messageKey: number) => {
  console.log(`用户请求重新生成消息 ${messageKey}`);
  // 获取对应的用户消息
  const userMessageIndex = messageKey - 1;
  if (
    userMessageIndex >= 0 &&
    messages.value[userMessageIndex]?.role === "user"
  ) {
    const userMessage = messages.value[userMessageIndex].content;

    // 设置当前消息为加载状态
    messages.value[messageKey].content = "正在重新生成...";
    loading.value = true;

    // 调用API重新生成回答
    fetchStreamData(userMessage, 2); // 假设操作类型3表示重新生成
  } else {
    messageApi.error("无法找到对应的用户消息");
  }
};

// 定义角色样式
const roles: BubbleListProps["roles"] = {
  ai: {
    placement: "start",
    avatar: {
      icon: <UserOutlined />,
      style: { background: "#fde3cf" }
    },
    typing: {
      step: 2,
      interval: 10,
      suffix: <Fragment>💡</Fragment>
    },
    style: {
      maxWidth: "600px"
    },
    header: "AI助手",
    messageRender: renderMarkdown,
    // 添加自定义加载渲染
    loadingRender: () => (
      <Space>
        <Spin size="small" />
        正在思考中...
      </Space>
    )
  },
  user: {
    placement: "end",
    avatar: {
      icon: <UserOutlined />,
      style: { background: "#87d068" }
    },
    header: "用户"
  }
};

// 更新用户头像和名称的函数
const updateUserAvatar = () => {
  if (userAvatar.value) {
    // 类型断言，确保roles.user是正确的类型
    const userRole = roles.user as any;
    userRole.avatar = { src: userAvatar.value };
  }
  if (userName.value) {
    const userRole = roles.user as any;
    userRole.header = userName.value;
  }
};

// 引用BubbleList组件实例
const listRef = ref<InstanceType<typeof BubbleList>>(null);

// 添加模型选择相关状态
interface AIModel {
  id: string;
  modelName: string;
  modelUrl: string;
  createUser: string | null;
  updateUser: string | null;
  createTime: string | null;
  updateTime: string | null;
  createUserNumber: string | null;
  updateUserNumber: string | null;
}

const modelList = ref<AIModel[]>([]);
const selectedModelId = ref<string>("");
const selectedModelUrl = ref<string>("http://localhost:8080"); // 设置默认URL

// 获取模型列表
const fetchModelList = async () => {
  try {
    const res = await getAllModels();
    if (res && res.data && Array.isArray(res.data)) {
      modelList.value = res.data;

      // 如果有模型，默认选择第一个
      if (modelList.value.length > 0) {
        selectedModelId.value = modelList.value[0].id;
        selectedModelUrl.value = modelList.value[0].modelUrl;
      }
    } else {
      console.error("获取模型列表失败:", res);
      messageApi.error("获取模型列表失败");
    }
  } catch (error) {
    console.error("获取模型列表出错:", error);
    messageApi.error("获取模型列表出错");
  }
};

// 处理模型选择变更
const handleModelChange = (value: string) => {
  const selectedModel = modelList.value.find(model => model.id === value);
  if (selectedModel) {
    selectedModelId.value = selectedModel.id;
    selectedModelUrl.value = selectedModel.modelUrl;
    console.log(
      `已选择模型: ${selectedModel.modelName}, URL: ${selectedModel.modelUrl}`
    );
  }
};

// 替换原有的fetchStreamData函数，使用导入的API
const fetchStreamData = async (message: string, operationType: number = 0) => {
  try {
    loading.value = true;

    // 获取最后一条消息的索引
    const lastMessageIndex = messages.value.length - 1;

    // 使用API模块中的函数处理流式响应，传入选中的模型URL和会话ID
    await fetchAIStreamData(
      message,
      {
        onStart: () => {
          loading.value = true;
        },
        onData: result => {
          // 收到数据后，清除loading状态
          if (loading.value) {
            loading.value = false;
          }

          // 更新最后一条消息的内容
          if (lastMessageIndex >= 0) {
            messages.value[lastMessageIndex].content = result;
          }
        },
        onComplete: () => {
          loading.value = false;

          // 响应完成后，为AI消息添加底部按钮
          if (
            lastMessageIndex >= 0 &&
            messages.value[lastMessageIndex].role === "ai"
          ) {
            const content = messages.value[lastMessageIndex].content;
            // 使用自定义渲染函数创建底部按钮
            messages.value[lastMessageIndex].footer = renderMessageFooter(
              content,
              lastMessageIndex
            );
          }
        },
        onError: error => {
          console.error("Error fetching stream data:", error);
          loading.value = false;
        }
      },
      selectedModelUrl.value,
      currentConversationId.value,
      operationType
    );
  } catch (error) {
    console.error("Error in fetchStreamData:", error);
    loading.value = false;
  }
};

// 添加文件处理动画效果状态
const fileAddInProgress = ref(false);

// 处理文件上传
const handleFileUpload = async ({ file }: { file: any }) => {
  if (!file) {
    messageApi.error("文件上传失败，请重试！");
    return;
  }

  // 检查文件类型
  const isDocxFile = file.name.endsWith(".docx");
  const isDocFile = file.name.endsWith(".doc");
  const isWordFile = isDocxFile || isDocFile;
  const isExcelFile = file.name.endsWith(".xlsx") || file.name.endsWith(".xls");

  if (!isWordFile && !isExcelFile) {
    messageApi.error("只支持上传Word和Excel文件！");
    return;
  }

  // 对于旧版.doc文件，给出特殊提示
  if (isDocFile) {
    messageApi.warning(
      "注意：系统对旧版.doc格式支持有限，请尽量使用.docx格式。如果解析失败，请将文件转换为.docx格式后重试。"
    );
  }

  // 检查文件大小，限制在10MB以内
  if (file.size > 10 * 1024 * 1024) {
    messageApi.error("文件大小不能超过10MB！");
    return;
  }

  try {
    // 激活文件添加动画状态
    fileAddInProgress.value = true;

    // 创建一个新的文件对象，用于显示
    const newFile: UploadedFile = {
      uid: Date.now().toString(),
      name: file.name,
      size: file.size,
      status: "uploading",
      type: isWordFile ? "word" : "excel"
    };

    // 添加到文件列表（创建新数组）
    uploadedFiles.value = [...uploadedFiles.value, newFile];

    // 延迟重置添加动画状态，让过渡效果有时间显示
    setTimeout(() => {
      fileAddInProgress.value = false;
    }, 600);

    // 读取文件内容
    const reader = new FileReader();

    reader.onload = async e => {
      try {
        if (!e.target?.result) {
          throw new Error("读取文件内容失败");
        }

        let content = "";

        // 解析Word文档
        if (isWordFile) {
          try {
            const arrayBuffer = e.target.result as ArrayBuffer;
            // 尝试使用mammoth解析
            const result = await mammoth.extractRawText({ arrayBuffer });
            content = result.value || "【无法提取文档内容】";
          } catch (error) {
            console.error("Word文档解析错误:", error);

            // 针对.doc格式的特殊处理
            if (isDocFile) {
              content =
                "【无法解析旧版.doc格式文件】请将文件转换为.docx格式后重试，或直接复制文档内容到对话框中。";
              messageApi.error(
                "无法解析旧版.doc格式文件，请转换为.docx格式后重试。"
              );
            } else {
              content = "【文档解析失败】请检查文件格式是否正确。";
              messageApi.error(`解析文件 ${file.name} 失败！`);
            }
          }
        }

        // 解析Excel文档
        if (isExcelFile) {
          try {
            const arrayBuffer = e.target.result as ArrayBuffer;
            const workbook = XLSX.read(arrayBuffer, { type: "array" });

            // 读取所有工作表
            const sheets = workbook.SheetNames;
            if (sheets.length === 0) {
              content = "【表格内容为空】";
            } else {
              content = sheets
                .map(sheetName => {
                  const sheet = workbook.Sheets[sheetName];
                  return `【${sheetName}】\n${XLSX.utils.sheet_to_csv(sheet) || "【表格内容为空】"}`;
                })
                .join("\n\n");
            }
          } catch (error) {
            console.error("Excel文档解析错误:", error);
            content = "【表格解析失败】请检查文件格式是否正确。";
            messageApi.error(`解析文件 ${file.name} 失败！`);
          }
        }

        // 更新文件状态和内容（创建新的数组和对象）
        const fileIndex = uploadedFiles.value.findIndex(
          f => f.uid === newFile.uid
        );
        if (fileIndex > -1) {
          const updatedFiles = [...uploadedFiles.value];
          updatedFiles[fileIndex] = {
            ...updatedFiles[fileIndex],
            status: "done",
            content
          };
          uploadedFiles.value = updatedFiles;

          // 将解析出的内容添加到全局变量，准备和用户输入一起发送
          parsedFileContent.value = uploadedFiles.value
            .map(f => f.content)
            .filter(Boolean)
            .join("\n\n");

          if (
            !content.includes("【无法解析") &&
            !content.includes("【文档解析失败】") &&
            !content.includes("【表格解析失败】")
          ) {
            messageApi.success(`文件 ${file.name} 解析成功！`);
          }
        }
      } catch (error) {
        console.error("解析文件失败:", error);
        messageApi.error(`解析文件 ${file.name} 失败！`);

        // 更新文件状态为错误
        const fileIndex = uploadedFiles.value.findIndex(
          f => f.uid === newFile.uid
        );
        if (fileIndex > -1) {
          const updatedFiles = [...uploadedFiles.value];
          updatedFiles[fileIndex] = {
            ...updatedFiles[fileIndex],
            status: "error"
          };
          uploadedFiles.value = updatedFiles;
        }
      }
    };

    reader.onerror = () => {
      messageApi.error(`读取文件 ${file.name} 失败！`);

      // 更新文件状态为错误
      const fileIndex = uploadedFiles.value.findIndex(
        f => f.uid === newFile.uid
      );
      if (fileIndex > -1) {
        const updatedFiles = [...uploadedFiles.value];
        updatedFiles[fileIndex] = {
          ...updatedFiles[fileIndex],
          status: "error"
        };
        uploadedFiles.value = updatedFiles;
      }
    };

    // 开始读取文件
    reader.readAsArrayBuffer(file);
  } catch (error) {
    fileAddInProgress.value = false;
    console.error("上传文件处理失败:", error);
    messageApi.error("上传文件处理失败！");
  }
};

// 移除文件
const handleRemoveFile = (file: UploadedFile) => {
  if (!file || !file.uid) return;

  try {
    // 标记文件为正在移除
    const fileIndex = uploadedFiles.value.findIndex(f => f.uid === file.uid);
    if (fileIndex > -1) {
      const updatedFiles = [...uploadedFiles.value];
      updatedFiles[fileIndex] = {
        ...updatedFiles[fileIndex],
        status: "removed"
      };
      uploadedFiles.value = updatedFiles;

      // 延迟实际移除文件，让动画有时间展示
      setTimeout(() => {
        // 创建一个新的数组而不是直接修改
        uploadedFiles.value = uploadedFiles.value.filter(
          f => f.uid !== file.uid
        );

        // 如果移除了所有文件，清空解析内容
        if (uploadedFiles.value.length === 0) {
          parsedFileContent.value = "";
        }
      }, 300);
    }
  } catch (error) {
    console.error("删除文件失败:", error);
  }
};

// 处理文件上传点击事件
const handleUploadClick = () => {
  // 创建一个隐藏的文件输入框
  const input = document.createElement("input");
  input.type = "file";
  input.accept = ".docx,.xlsx,.xls"; // 移除.doc，更推荐使用.docx格式
  input.style.display = "none";

  // 在点击前显示支持的文件格式提示
  messageApi.info("请选择.docx或Excel文件上传，不建议使用旧版.doc格式");

  // 监听文件选择事件
  input.onchange = e => {
    const target = e.target as HTMLInputElement;
    if (target.files && target.files.length > 0) {
      const file = target.files[0];
      // 调用上传处理函数
      handleFileUpload({ file });
    }
  };

  // 触发点击事件
  document.body.appendChild(input);
  input.click();

  // 使用完后移除
  setTimeout(() => {
    document.body.removeChild(input);
  }, 100);
};

// 添加消息滚动函数，带平滑滚动效果
const scrollToLatestMessage = async () => {
  await nextTick(); // 等待DOM更新
  listRef.value?.scrollTo({
    key: messages.value.length - 1,
    block: "nearest",
    behavior: "smooth" // 添加平滑滚动效果
  });
};

// 获取历史会话列表
const fetchHistoryConversations = async () => {
  try {
    loadingHistory.value = true;
    const res = await getSessionIdsAndLastData();
    if (res && res.data && Array.isArray(res.data)) {
      conversationHistory.value = res.data;
      console.log("获取历史会话成功:", conversationHistory.value);
    } else {
      console.error("获取历史会话失败:", res);
      messageApi.error("获取历史会话失败");
    }
  } catch (error) {
    console.error("获取历史会话出错:", error);
    messageApi.error("获取历史会话出错");
  } finally {
    loadingHistory.value = false;
  }
};

// 创建新会话
const createConversation = async () => {
  try {
    const res = await createNewSession();
    if (res && res.data) {
      currentConversationId.value = res.data;
      // 清空当前消息
      messages.value = [];
      messageApi.success("创建新会话成功");
      // 只在移动端关闭历史抽屉
      if (!isPC.value) {
        historyDrawerVisible.value = false;
      }
    } else {
      console.error("创建新会话失败:", res);
      messageApi.error("创建新会话失败");
    }
  } catch (error) {
    console.error("创建新会话出错:", error);
    messageApi.error("创建新会话出错");
  }
};

// 切换到指定会话
const switchToConversation = async (conversationId: string) => {
  try {
    if (currentConversationId.value === conversationId) {
      // 只在移动端关闭历史抽屉
      if (!isPC.value) {
        historyDrawerVisible.value = false;
      }
      return;
    }

    loadingHistory.value = true;
    // 获取指定会话的内容
    const res = await getSessionContent(conversationId);
    console.log("获取会话内容响应:", res);

    if (res && res.data) {
      // 更新当前会话ID
      currentConversationId.value = conversationId;

      // 将会话内容转换为消息格式
      const historyMessages: Message[] = [];
      let messageIndex = 0;

      // 处理JSON示例中提供的API响应格式
      if (Array.isArray(res.data)) {
        console.log("历史消息数组:", res.data);
        res.data.forEach(item => {
          console.log("处理历史消息项:", item);

          // 确保userInput存在再添加用户消息
          if (item && item.userInput) {
            historyMessages.push({
              key: messageIndex++,
              role: "user",
              content: item.userInput
            });
          }

          // 确保aiOutput存在再添加AI消息
          if (item && item.aiOutput) {
            const aiMessageKey = messageIndex++;
            historyMessages.push({
              key: aiMessageKey,
              role: "ai",
              content: item.aiOutput,
              // 为历史AI消息添加底部按钮
              footer: renderMessageFooter(item.aiOutput, aiMessageKey)
            });
          }
        });
      }

      console.log("转换后的消息列表:", historyMessages);
      // 更新消息列表
      messages.value = historyMessages;

      // 只在移动端关闭历史抽屉
      if (!isPC.value) {
        historyDrawerVisible.value = false;
      }

      // 滚动到最新消息
      nextTick(() => {
        scrollToLatestMessage();
      });

      messageApi.success("切换会话成功");
    } else {
      console.error("获取会话内容失败:", res);
      messageApi.error("获取会话内容失败");
    }
  } catch (error) {
    console.error("切换会话出错:", error);
    messageApi.error("切换会话出错");
  } finally {
    loadingHistory.value = false;
  }
};

// 处理历史项点击
const handleHistoryItemClick = (conversationId: string) => {
  console.log("历史项点击事件触发", conversationId);
  if (!conversationId) {
    console.error("点击的历史项缺少conversationId");
    return;
  }
  // 添加更多日志，帮助调试
  console.log("handleHistoryItemClick - conversationId:", conversationId);
  switchToConversation(conversationId);
};

// 格式化历史会话项
const formattedHistoryItems = computed(() => {
  return conversationHistory.value.map(conv => {
    // 提取日期时间
    const dateObj = new Date(conv.lastMessageTime);
    const formattedDate = `${dateObj.getFullYear()}-${String(dateObj.getMonth() + 1).padStart(2, "0")}-${String(dateObj.getDate()).padStart(2, "0")} ${String(dateObj.getHours()).padStart(2, "0")}:${String(dateObj.getMinutes()).padStart(2, "0")}`;

    // 截断过长的消息
    const truncatedInput =
      conv.lastUserInput.length > 30
        ? conv.lastUserInput.substring(0, 30) + "..."
        : conv.lastUserInput;

    return {
      key: conv.conversationId,
      title: truncatedInput || "新会话",
      time: formattedDate
    };
  });
});

// 打开历史抽屉
const openHistoryDrawer = () => {
  fetchHistoryConversations();
  historyDrawerVisible.value = true;
};

// 关闭历史抽屉
const closeHistoryDrawer = () => {
  historyDrawerVisible.value = false;
};

// 切换历史抽屉状态
const toggleHistoryDrawer = () => {
  if (historyDrawerVisible.value) {
    closeHistoryDrawer();
  } else {
    openHistoryDrawer();
  }
};

// 自定义渲染AI消息底部按钮
const renderMessageFooter = (content: string, key: number) => {
  // 确保内容存在
  if (!content) return null;

  return (
    <Flex class="message-footer-buttons">
      <AButton
        size="small"
        type="text"
        icon={<SyncOutlined />}
        class="footer-button regenerate-button"
        onClick={() => handleRegenerate(key)}
        title="重新生成"
      />
      <div style="margin-left: auto;">
        <AButton
          size="small"
          type="text"
          icon={<CopyOutlined />}
          class="footer-button"
          onClick={() => copyToClipboard(content)}
          title="复制内容"
        />
        <AButton
          size="small"
          type="text"
          icon={<SmileOutlined />}
          class="footer-button"
          onClick={() => handleFeedback("like", content, key)}
          title="有帮助"
        />
        <AButton
          size="small"
          type="text"
          icon={<FrownOutlined />}
          class="footer-button"
          onClick={() => handleFeedback("dislike", content, key)}
          title="没帮助"
        />
      </div>
    </Flex>
  );
};

// 修改sendMessage函数以支持会话ID
const sendMessage = async (message: string) => {
  // 组合用户输入和文件内容
  let combinedMessage = message.trim();

  // 如果有解析的文件内容，添加到消息中
  if (parsedFileContent.value) {
    combinedMessage = `${combinedMessage}\n\n【附件内容】:\n${parsedFileContent.value}`;
  }

  // 如果没有内容，不发送
  if (!combinedMessage) return;

  // 如果当前没有会话ID，创建新会话
  if (!currentConversationId.value) {
    try {
      const res = await createNewSession();
      if (res && res.data) {
        currentConversationId.value = res.data;
      } else {
        console.error("自动创建会话失败:", res);
        messageApi.error("创建会话失败，请重试");
        return;
      }
    } catch (error: any) {
      console.error("自动创建会话出错:", error);
      messageApi.error("创建会话失败，请重试");
      return;
    }
  }

  // 添加用户消息
  messages.value.push({
    key: messages.value.length,
    role: "user",
    content: combinedMessage
  });

  // 添加AI消息占位
  messages.value.push({
    key: messages.value.length,
    role: "ai",
    content: "正在思考...",
    footer: null // 确保加载中的消息没有底部按钮
  });

  // 先触发清空输入框的动画效果
  inputClearActive.value = true;

  // 延迟一小段时间再实际清空，以便动画效果展示
  setTimeout(() => {
    // 清空输入框和文件内容
    value.value = "";
    parsedFileContent.value = "";
    uploadedFiles.value = [];

    // 重置清空动画状态
    setTimeout(() => {
      inputClearActive.value = false;
    }, 300);
  }, 150);

  // 使用平滑滚动
  await scrollToLatestMessage();

  // 确定操作类型
  let operationType = 0; // 默认为新建对话
  if (currentConversationId.value) {
    operationType = 2; // 已有会话ID，使用继续对话模式
  }

  // 调用接口获取流式数据，传递会话ID和操作类型
  await fetchStreamData(combinedMessage, operationType);
};

// 添加输入框动画状态
const inputClearActive = ref(false);
const inputChangeTimeout = ref<number | null>(null);
const inputTypingActive = ref(false);

// 监听输入变化，添加输入时的动画效果
const handleInputChange = (v: string) => {
  // 清除之前的计时器
  if (inputChangeTimeout.value !== null) {
    clearTimeout(inputChangeTimeout.value);
  }

  // 设置输入状态为活跃
  inputTypingActive.value = true;

  // 设置一个计时器，在用户停止输入后重置状态
  inputChangeTimeout.value = window.setTimeout(() => {
    inputTypingActive.value = false;
  }, 1000);

  value.value = v;
  changeValue(v);
};

const changeValue = (v: string) => {
  console.log("changeValue", v);
};

const cancel = () => {
  console.log("cancel");
};

const value = ref("");

// 模式选择：自然对话或OCR
const selectedMode = ref("chat");

// 处理模式按钮点击
const handleModeButtonClick = (mode: string) => {
  if (mode === selectedMode.value) return;
  selectedMode.value = mode;

  if (mode === "ocr") {
    // 使用window.location.href跳转到OCR页面
    window.location.href = "#/OCR";
  }
};

// 检测是否为PC端设备
const checkDeviceType = () => {
  // 小于768px视为移动端，否则为PC端
  isPC.value = window.innerWidth > 768;

  // 如果是PC端，默认展开侧边栏
  if (isPC.value) {
    historyDrawerVisible.value = true;
  }
};

// 添加窗口大小变化监听
const handleResize = () => {
  checkDeviceType();
};

// 初始化
onMounted(() => {
  getUserInfo();
  fetchModelList(); // 获取模型列表
  fetchHistoryConversations(); // 获取历史会话列表
  // 检测设备类型
  checkDeviceType();
  // 添加窗口大小变化监听
  window.addEventListener("resize", handleResize);
  setTimeout(() => {
    createWatermark();
    updateUserAvatar(); // 更新用户头像和名称
  }, 100);
});

// 组件卸载时移除事件监听
onUnmounted(() => {
  window.removeEventListener("resize", handleResize);
});

// 添加文件预览相关状态
const previewDrawerVisible = ref(false);
const currentPreviewFile = ref<UploadedFile | null>(null);
const previewContent = ref<string>("");

// 处理文件预览
const handlePreviewFile = (file: UploadedFile) => {
  currentPreviewFile.value = file;
  previewContent.value = file.content || "";
  previewDrawerVisible.value = true;
};

// 关闭预览抽屉
const closePreviewDrawer = () => {
  previewDrawerVisible.value = false;
  currentPreviewFile.value = null;
  previewContent.value = "";
};

// 添加文件内容展开状态管理
const expandedFiles = ref<Set<string>>(new Set());

// 处理文件内容展开/折叠
const toggleFileContent = (fileUid: string) => {
  if (expandedFiles.value.has(fileUid)) {
    expandedFiles.value.delete(fileUid);
  } else {
    expandedFiles.value.add(fileUid);
  }
};

// 获取缩略内容
const getTruncatedContent = (content: string, maxLength: number = 200) => {
  if (!content) return "";
  if (content.length <= maxLength) return content;
  return content.slice(0, maxLength) + "...";
};
</script>

<template>
  <div class="ai-chat-container">
    <!-- 水印组件 -->
    <!-- <div ref="watermarkDiv" class="watermark" /> -->

    <!-- 添加Logo背景 -->
    <div class="logo-background" />

    <!-- PC端专用侧边栏 -->
    <div
      v-if="isPC"
      class="pc-sidebar"
      :class="{ 'pc-sidebar-hidden': !historyDrawerVisible }"
    >
      <div class="pc-sidebar-header">
        <div class="pc-sidebar-title">历史会话</div>
        <AButton
          type="text"
          class="pc-sidebar-close"
          @click="closeHistoryDrawer"
        >
          <template #icon><CloseOutlined /></template>
        </AButton>
      </div>

      <div class="history-header">
        <AButton
          type="primary"
          class="new-conversation-btn"
          @click="createConversation"
        >
          <template #icon><PlusOutlined /></template>
          新建会话
        </AButton>
      </div>

      <div v-if="loadingHistory" class="history-loading">加载历史会话中...</div>

      <div v-else-if="conversationHistory.length === 0" class="empty-history">
        暂无历史会话
      </div>

      <div v-else class="conversation-list">
        <List :data-source="formattedHistoryItems" item-layout="horizontal">
          <template #renderItem="{ item }">
            <List.Item
              :class="{
                'active-conversation': item.key === currentConversationId
              }"
              class="conversation-item"
              @click="handleHistoryItemClick(item.key)"
            >
              <div class="history-item">
                <div class="history-item-title">
                  {{ item.title || "新会话" }}
                </div>
                <div class="history-item-time">{{ item.time }}</div>
              </div>
            </List.Item>
          </template>
        </List>
      </div>
    </div>

    <!-- 移动端抽屉 -->
    <Drawer
      v-if="!isPC"
      :visible="historyDrawerVisible"
      :closable="true"
      :width="300"
      placement="left"
      title="历史会话"
      @close="closeHistoryDrawer"
    >
      <div class="history-header">
        <AButton
          type="primary"
          class="new-conversation-btn"
          @click="createConversation"
        >
          <template #icon><PlusOutlined /></template>
          新建会话
        </AButton>
      </div>

      <div v-if="loadingHistory" class="history-loading">加载历史会话中...</div>

      <div v-else-if="conversationHistory.length === 0" class="empty-history">
        暂无历史会话
      </div>

      <div v-else class="conversation-list">
        <List :data-source="formattedHistoryItems" item-layout="horizontal">
          <template #renderItem="{ item }">
            <List.Item
              :class="{
                'active-conversation': item.key === currentConversationId
              }"
              class="conversation-item"
              @click="handleHistoryItemClick(item.key)"
            >
              <div class="history-item">
                <div class="history-item-title">
                  {{ item.title || "新会话" }}
                </div>
                <div class="history-item-time">{{ item.time }}</div>
              </div>
            </List.Item>
          </template>
        </List>
      </div>
    </Drawer>

    <!-- 添加文件预览抽屉 -->
    <Drawer
      :visible="previewDrawerVisible"
      :width="500"
      placement="right"
      :title="currentPreviewFile?.name || '文件预览'"
      @close="closePreviewDrawer"
    >
      <div class="preview-content">
        <pre
          v-if="currentPreviewFile?.type === 'excel'"
          class="preview-excel"
          >{{ previewContent }}</pre
        >
        <div v-else class="preview-text">{{ previewContent }}</div>
      </div>
    </Drawer>

    <div
      class="chat-content"
      :class="{ 'pc-content': isPC && historyDrawerVisible }"
    >
      <!-- 欢迎组件过渡效果 -->
      <transition name="welcome-fade">
        <div v-if="messages.length === 0" class="welcome-container">
          <Welcome
            title="您好，我是农大智能助手"
            description="基于Ant Design的AGI产品界面解决方案，创造更好的智能视觉体验~"
            class="welcome-component"
          >
            <template #icon>
              <div class="welcome-icon-wrapper">
                <img
                  src="@/assets/农宝通.png"
                  alt="农宝通LOGO"
                  class="welcome-icon"
                />
              </div>
            </template>
          </Welcome>
        </div>
      </transition>

      <!-- 使用BubbleList组件替换原来的Bubble组件 -->
      <div class="message-list-container">
        <BubbleList
          ref="listRef"
          style="
            max-height: calc(100vh - 150px);
            overflow-y: auto;
            scroll-behavior: smooth;
          "
          :roles="roles"
          :items="messages"
          :loading="loading ? messages.length - 1 : undefined"
        />
      </div>
    </div>
    <div
      class="sender-container"
      :class="{ 'pc-sender': isPC && historyDrawerVisible }"
    >
      <!-- 添加模型选择器 -->
      <transition name="slide-up">
        <div v-show="true" class="model-selector">
          <!-- 历史会话按钮移到模型选择左侧 - 只在非PC端显示 -->
          <AButton
            type="text"
            class="mode-button no-shrink"
            title="历史会话"
            @click="toggleHistoryDrawer"
          >
            <template #icon><HistoryOutlined /></template>
            历史会话
          </AButton>

          <!-- 添加上传文件按钮 -->
          <AButton
            type="text"
            class="mode-button no-shrink"
            title="上传文件"
            @click="handleUploadClick"
          >
            <template #icon><CloudUploadOutlined /></template>
            上传文件
          </AButton>

          <!-- 只有当模型列表长度大于1时才显示Select -->
          <Select
            v-if="modelList.length > 1"
            v-model:value="selectedModelId"
            class="model-select"
            placeholder="请选择AI模型"
            @change="handleModelChange"
          >
            <Select.Option
              v-for="model in modelList"
              :key="model.id"
              :value="model.id"
            >
              {{ model.modelName }}
            </Select.Option>
          </Select>

          <AButton
            type="text"
            class="mode-button no-shrink"
            :class="{ 'mode-active': selectedMode === 'ocr' }"
            title="OCR识别"
            @click="handleModeButtonClick('ocr')"
          >
            <template #icon><ScanOutlined /></template>
            OCR识别
          </AButton>
        </div>
      </transition>

      <!-- 将文件卡片移到这里，显示在输入框上方 -->
      <transition name="file-list">
        <div
          v-if="uploadedFiles.length > 0"
          class="file-cards-container"
          :class="{ 'file-adding': fileAddInProgress }"
        >
          <div class="file-cards-header">已上传文件：</div>
          <div class="files-wrapper">
            <transition-group
              name="file-card"
              tag="div"
              class="files-transition-group"
            >
              <div
                v-for="file in uploadedFiles"
                :key="file.uid"
                class="file-card"
                :class="{ 'file-removing': file.status === 'removed' }"
              >
                <Card class="file-card-content" :bordered="false">
                  <template #title>
                    <Space>
                      <CloudUploadOutlined />
                      <span>{{ file.name }}</span>
                      <Tag v-if="file.type === 'excel'" color="blue">Excel</Tag>
                      <Tag v-else color="green">Word</Tag>
                    </Space>
                  </template>
                  <template #extra>
                    <Space>
                      <Popconfirm
                        title="确定要删除此文件吗？"
                        @confirm="handleRemoveFile(file)"
                      >
                        <AButton type="text" danger>
                          <template #icon><DeleteOutlined /></template>
                        </AButton>
                      </Popconfirm>
                    </Space>
                  </template>
                  <div
                    class="file-content-preview"
                    :class="{ 'is-expanded': expandedFiles.has(file.uid) }"
                  >
                    <template v-if="file.type === 'excel'">
                      <pre
                        class="preview-excel"
                        :class="{ truncated: !expandedFiles.has(file.uid) }"
                        >{{
                          expandedFiles.has(file.uid)
                            ? file.content
                            : getTruncatedContent(file.content)
                        }}</pre
                      >
                    </template>
                    <template v-else>
                      <div
                        class="preview-text"
                        :class="{ truncated: !expandedFiles.has(file.uid) }"
                      >
                        {{
                          expandedFiles.has(file.uid)
                            ? file.content
                            : getTruncatedContent(file.content)
                        }}
                      </div>
                    </template>
                    <div
                      class="expand-button"
                      @click="toggleFileContent(file.uid)"
                    >
                      <AButton type="link">
                        {{ expandedFiles.has(file.uid) ? "收起" : "展开" }}
                        <template #icon>
                          <component
                            :is="
                              expandedFiles.has(file.uid)
                                ? 'UpOutlined'
                                : 'DownOutlined'
                            "
                          />
                        </template>
                      </AButton>
                    </div>
                  </div>
                </Card>
              </div>
            </transition-group>
          </div>
        </div>
      </transition>

      <!-- 修改输入框结构，将上传按钮放入Sender组件内部 -->
      <transition name="slide-up">
        <div
          v-show="true"
          class="input-container"
          :class="{
            'input-typing': inputTypingActive,
            'input-clear': inputClearActive
          }"
        >
          <Sender
            v-model:value="value"
            :loading="loading"
            style="flex: 1"
            @submit="sendMessage"
            @cancel="cancel"
            @change="handleInputChange"
          >
            <!-- 使用插槽将上传按钮放入Sender组件内部 -->
            <template #prefix>
              <Button
                type="text"
                class="upload-button"
                @click="handleUploadClick"
              >
                <template #icon><CloudUploadOutlined /></template>
              </Button>
            </template>
          </Sender>
        </div>
      </transition>
    </div>
  </div>
</template>

<style scoped>
@keyframes fade-in {
  from {
    opacity: 0;
  }

  to {
    opacity: 1;
  }
}

@keyframes scale-in {
  from {
    opacity: 0;
    transform: scale(0.95);
  }

  to {
    opacity: 1;
    transform: scale(1);
  }
}

@keyframes slide-down {
  from {
    opacity: 0;
    transform: translateY(-30px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes slide-up {
  from {
    opacity: 0;
    transform: translateY(30px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* 输入框提交时的弹性动画 */
@keyframes clear-text-effect {
  0% {
    opacity: 1;
    transform: scale(1);
  }

  30% {
    opacity: 0.8;
    transform: scale(0.98);
  }

  100% {
    opacity: 1;
    transform: scale(1);
  }
}

@keyframes file-adding-pulse {
  0% {
    background-color: #f8f8f8;
    box-shadow: 0 2px 8px rgb(0 0 0 / 5%);
  }

  50% {
    background-color: #e6f7ff;
    box-shadow: 0 4px 12px rgb(24 144 255 / 20%);
  }

  100% {
    background-color: #f8f8f8;
    box-shadow: 0 2px 8px rgb(0 0 0 / 5%);
  }
}

/* LOGO背景淡入缩放 */
@keyframes logo-fade-in {
  0% {
    opacity: 0;
    transform: scale(1.2);
  }

  30% {
    opacity: 0.03;
  }

  70% {
    opacity: 0.08;
  }

  100% {
    opacity: 0.1;
    transform: scale(1);
  }
}

@keyframes message-expand {
  from {
    opacity: 0;
    transform: translateY(-10px) scale(0.98);
  }

  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

@keyframes user-message-slide {
  0% {
    opacity: 0;
    transform: translateY(5px) translateX(15px) scale(0.95);
  }

  100% {
    opacity: 1;
    transform: translateY(0) translateX(0) scale(1);
  }
}

@keyframes ai-message-slide {
  0% {
    opacity: 0;
    transform: translateY(5px) translateX(-15px) scale(0.95);
  }

  100% {
    opacity: 1;
    transform: translateY(0) translateX(0) scale(1);
  }
}

@keyframes button-ripple {
  0% {
    opacity: 1;
    transform: scale(0.2);
  }

  100% {
    opacity: 0;
    transform: scale(2);
  }
}

@keyframes slide-in-right {
  from {
    opacity: 0;
    transform: translateX(-20px);
  }

  to {
    opacity: 1;
    transform: translateX(0);
  }
}

@keyframes fade-in-up {
  from {
    opacity: 0;
    transform: translateY(10px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* 思维链相关动画 */
@keyframes think-fade-in {
  from {
    opacity: 0;
    transform: translateY(-5px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* 添加响应式动画 */
@media (width <= 768px) {
  .welcome-component,
  .prompts-component {
    animation-duration: 0.4s;
  }

  .input-container,
  .model-selector {
    animation-duration: 0.3s;
  }
}

/* 优化输入框在不同设备上的表现 */
@media (width <= 768px) {
  .sender-container {
    width: 92%;
    margin: 0 auto;
    margin-bottom: 10px;
  }
}

/* 优化输入容器的宽度，让其在不同屏幕尺寸上更合理 */
@media (width >= 1440px) {
  .pc-sender {
    width: calc(90% - 300px);
    margin-left: calc(300px + 5%);
  }
}

@media (width >= 1920px) {
  .pc-sender {
    width: calc(85% - 300px);
    margin-left: calc(300px + 7.5%);
  }
}

/* 移动端适配 */
@media (width <= 768px) {
  .welcome-icon-wrapper {
    width: 50px;
    min-width: 50px; /* 防止被挤压 */
    height: 50px;
    margin-top: 10px;
  }
}

.ai-chat-container {
  display: flex;
  flex-direction: column;
  height: 98%;

  /* 添加整体淡入效果 */
  animation: fade-in 0.8s ease-in-out;
}

.chat-content {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 16px;
  padding-top: 20px;
  padding-right: 20px;
  padding-left: 20px;
  scroll-behavior: smooth; /* 平滑滚动 */
}

.welcome-container {
  animation: scale-in 0.5s ease-out;
}

.welcome-component {
  transform-origin: center top;
  animation: slide-down 0.6s ease-out;
}

.prompts-component {
  animation: slide-up 0.6s ease-out 0.2s backwards;
}

.message-list-container {
  position: relative;
}

/* 消息列表过渡效果 */
.message-list-enter-active,
.message-list-leave-active {
  transition: all 0.5s cubic-bezier(0.23, 1, 0.32, 1);
}

.message-list-enter-from,
.message-list-leave-to {
  opacity: 0;
  transform: translateY(30px);
}

.message-list-move {
  transition: transform 0.5s cubic-bezier(0.23, 1, 0.32, 1);
}

.sender-container {
  width: 95%;
  margin: 0 auto;
  margin-bottom: 10px;
  transition: all 0.3s cubic-bezier(0.23, 1, 0.32, 1); /* 添加过渡效果 */
}

/* 为PC端sender添加样式，与内容区域一致 */
.pc-sender {
  width: calc(95% - 300px);
  margin-left: calc(300px + 2.5%);
  transition: all 0.3s cubic-bezier(0.23, 1, 0.32, 1);
}

/* 输入框弹性动画 */
.input-container {
  position: relative;
  display: flex;
  gap: 8px;
  align-items: center;
  width: 100%; /* 设置宽度为100%，跟随父容器 */
  transition: all 0.3s cubic-bezier(0.23, 1, 0.32, 1);
  transform-origin: center bottom;
  animation: slide-up 0.5s ease-out;
}

/* 输入时的微妙效果 */
.input-typing {
  box-shadow: 0 2px 12px rgb(0 0 0 / 10%);
}

/* 清空输入内容时的动画效果 */
.input-clear {
  animation: clear-text-effect 0.4s ease-out;
}

/* 上传按钮动画效果 */
.upload-button {
  transition: transform 0.2s ease;
}

.upload-button:hover {
  transform: scale(1.15);
}

/* 模型选择器样式 */
.model-selector {
  display: flex;
  align-items: center;
  width: 100%; /* 确保宽度与父容器一致 */
  padding: 8px;
  margin-bottom: 10px;
  overflow: auto hidden;
  white-space: nowrap;
  scrollbar-color: rgb(0 0 0 / 20%) transparent;
  scrollbar-width: thin;
  background-color: #f8f8f8;
  border-radius: 8px;
  box-shadow: 0 2px 6px rgb(0 0 0 / 5%);
  transition: all 0.3s ease;
}

.model-selector::-webkit-scrollbar {
  height: 4px;
}

.model-selector::-webkit-scrollbar-track {
  background: transparent;
}

.model-selector::-webkit-scrollbar-thumb {
  background-color: rgb(0 0 0 / 20%);
  border-radius: 4px;
}

.model-selector:hover {
  box-shadow: 0 4px 12px rgb(0 0 0 / 10%);
}

/* 功能选择栏样式 */
.mode-selector {
  display: flex;
  align-items: center;
  padding-left: 16px;
  margin-left: auto;
}

/* 欢迎页面过渡效果 */
.welcome-fade-enter-active,
.welcome-fade-leave-active {
  transition:
    opacity 0.5s ease,
    transform 0.5s ease;
}

.welcome-fade-enter-from,
.welcome-fade-leave-to {
  opacity: 0;
  transform: scale(0.95);
}

/* 滑动效果 */
.slide-up-enter-active,
.slide-up-leave-active {
  transition: all 0.5s ease;
}

.slide-up-enter-from,
.slide-up-leave-to {
  opacity: 0;
  transform: translateY(20px);
}

/* 文件列表过渡效果 */
.file-list-enter-active {
  max-height: 300px;
  overflow: hidden;
  transition: all 0.5s cubic-bezier(0.23, 1, 0.32, 1);
}

.file-list-leave-active {
  max-height: 300px;
  overflow: hidden;
  transition: all 0.5s cubic-bezier(0.23, 1, 0.32, 1);
}

.file-list-enter-from {
  max-height: 0;
  opacity: 0;
  transform: translateY(-10px);
}

.file-list-leave-to {
  max-height: 0;
  opacity: 0;
  transform: translateY(-10px);
}

/* 文件卡片过渡效果 */
.files-transition-group {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.file-card-enter-active {
  transition: all 0.5s cubic-bezier(0.23, 1, 0.32, 1);
  transform-origin: left center;
}

.file-card-leave-active {
  position: absolute;
  transition: all 0.4s cubic-bezier(0.23, 1, 0.32, 1);
}

.file-card-enter-from {
  opacity: 0;
  transform: translateX(-30px) scale(0.9);
}

.file-card-leave-to {
  opacity: 0;
  transform: translateX(-30px) scale(0.9);
}

.file-card-move {
  transition: transform 0.5s cubic-bezier(0.23, 1, 0.32, 1);
}

/* 文件卡片容器样式 */
.file-cards-container {
  padding: 10px;
  margin-bottom: 10px;
  background-color: #f8f8f8;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgb(0 0 0 / 5%);
  transition: all 0.3s ease;
}

/* 添加文件时的动画效果 */
.file-adding {
  animation: file-adding-pulse 0.6s ease-in-out;
}

.file-cards-container:hover {
  box-shadow: 0 4px 12px rgb(0 0 0 / 10%);
}

.file-cards-header {
  margin-bottom: 5px;
  font-weight: bold;
}

.file-card {
  width: 100%;
  margin-bottom: 16px;
  transition: all 0.3s ease;
}

.file-card-content {
  background-color: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgb(0 0 0 / 8%);
  transition: all 0.3s ease;
}

.file-card-content:hover {
  box-shadow: 0 4px 12px rgb(0 0 0 / 12%);
}

.file-content-preview {
  position: relative;
  max-height: 200px;
  padding: 12px;
  margin-top: 8px;
  overflow: hidden;
  background-color: #fafafa;
  border-radius: 4px;
  transition: all 0.3s ease;
}

.file-content-preview.is-expanded {
  max-height: 500px;
  overflow-y: auto;
}

.preview-text.truncated,
.preview-excel.truncated {
  position: relative;
  max-height: 150px;
  overflow: hidden;
  mask-image: linear-gradient(to bottom, #000 60%, transparent 100%);
}

.expand-button {
  position: absolute;
  bottom: 0;
  left: 0;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  padding: 4px 0;
  background: linear-gradient(to bottom, transparent, #fafafa 40%);
}

.expand-button .ant-btn-link {
  font-size: 13px;
}

.expand-button .anticon {
  margin-left: 4px;
  font-size: 12px;
}

/* 添加滚动条样式 */
.file-content-preview::-webkit-scrollbar {
  width: 6px;
  height: 6px;
}

.file-content-preview::-webkit-scrollbar-track {
  background: #f1f1f1;
  border-radius: 3px;
}

.file-content-preview::-webkit-scrollbar-thumb {
  background: #ccc;
  border-radius: 3px;
}

.file-content-preview::-webkit-scrollbar-thumb:hover {
  background: #999;
}

/* 文件卡片动画效果 */
.file-card-enter-active,
.file-card-leave-active {
  transition: all 0.5s ease;
}

.file-card-enter-from,
.file-card-leave-to {
  opacity: 0;
  transform: translateY(-20px);
}

.file-card:hover {
  transform: translateY(-2px);
}

/* 文件正在移除的动画效果 */
.file-removing {
  pointer-events: none;
  opacity: 0.5;
  transform: translateX(-10px) scale(0.95);
}

.files-wrapper {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

/* 水印样式 */
.watermark {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 9999;
  width: 100%;
  height: 100%;
  pointer-events: none;
  background-repeat: repeat;
  animation: fade-in 1.2s ease-in-out;
}

/* Logo背景样式 */
.logo-background {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 1;
  width: 100%;
  height: 100%;
  pointer-events: none;
  background-image: url("@/assets/logo.png");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 300px;
  opacity: 0;
  animation: logo-fade-in 1.5s ease-in-out forwards;
}

/* 顺滑的消息切换动画 */
.message-list-container :deep(.aiam-bubble-wrapper) {
  transition: all 0.3s cubic-bezier(0.23, 1, 0.32, 1);
  animation-fill-mode: both;
}

/* 消息展开效果 */
.message-list-container :deep(.aiam-bubble-wrapper:last-child) .aiam-bubble {
  transform-origin: top;
  animation: message-expand 0.3s cubic-bezier(0.23, 1, 0.32, 1);
}

/* 用户消息和AI消息不同的动画效果 */
.message-list-container :deep(.aiam-bubble-placement-end) {
  transform-origin: bottom right;
  animation: user-message-slide 0.4s cubic-bezier(0.23, 1, 0.32, 1);
}

.message-list-container :deep(.aiam-bubble-placement-start) {
  transform-origin: bottom left;
  animation: ai-message-slide 0.4s cubic-bezier(0.23, 1, 0.32, 1);
}

/* 添加Sender组件的深度样式 */
:deep(.aiam-sender) {
  width: 100%; /* 确保Sender组件宽度自适应 */
  transition: all 0.3s ease;
}

:deep(.aiam-sender-textarea) {
  transition: all 0.3s ease;
}

/* 发送按钮的特殊效果 */
:deep(.aiam-sender-send-button) {
  overflow: hidden;
  transition: all 0.3s cubic-bezier(0.23, 1, 0.32, 1) !important;
}

:deep(.aiam-sender-send-button:active) {
  transform: scale(0.92);
}

:deep(.aiam-sender-send-button:hover) {
  transform: translateY(-2px);
}

:deep(.aiam-sender-send-button:hover::after) {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  content: "";
  background: radial-gradient(
    circle,
    rgb(255 255 255 / 20%) 0%,
    rgb(255 255 255 / 0%) 70%
  );
  animation: button-ripple 0.8s ease-out;
}

/* 文本输入动画 */
:deep(.aiam-sender-textarea textarea) {
  transition: all 0.25s ease !important;
}

.input-typing :deep(.aiam-sender-textarea textarea) {
  background-color: rgb(255 255 255 / 95%);
}

/* 输入容器的焦点效果 */
.input-container:focus-within {
  box-shadow: 0 4px 16px rgb(0 0 0 / 8%);
  transform: translateY(-2px);
}

/* Markdown内容样式 */
:deep(.ant-typography) {
  color: inherit;
  transition: all 0.3s ease;
}

:deep(.markdown-body) {
  line-height: 1.6;
}

:deep(.katex) {
  display: inline-block !important;
  font-size: 1.1em;
  text-align: left;
}

:deep(.katex-display) {
  display: block;
  margin: 1em 0;
  overflow: auto hidden;
  text-align: center;
}

:deep(.katex-display > .katex) {
  display: inline-block !important;
  max-width: 100%;
  text-align: center;
}

:deep(.katex-display > .katex > .katex-html) {
  position: relative;
  display: block;
}

:deep(.markdown-body .katex) {
  margin: 5px 0;
  overflow: auto hidden;
  font-size: 1.1em;
  line-height: 1.4;
}

:deep(.markdown-body .katex-display) {
  padding: 8px 0;
  margin: 0.5em 0;
  overflow: auto hidden;
}

:deep(.ant-typography h1) {
  margin: 0.5em 0;
  font-size: 1.5em;
  animation: slide-in-right 0.5s ease;
}

:deep(.ant-typography h2) {
  margin: 0.5em 0;
  font-size: 1.3em;
  animation: slide-in-right 0.5s ease 0.1s backwards;
}

:deep(.ant-typography h3) {
  margin: 0.5em 0;
  font-size: 1.1em;
  animation: slide-in-right 0.5s ease 0.2s backwards;
}

:deep(.ant-typography p) {
  margin: 0.5em 0;
  transition: all 0.3s ease;
}

:deep(.ant-typography pre) {
  padding: 16px;
  margin: 0.5em 0;
  overflow: auto;
  background-color: #f6f8fa;
  border-radius: 6px;
  transition: all 0.3s ease;
  animation: fade-in-up 0.5s ease;
}

:deep(.ant-typography code) {
  padding: 0.2em 0.4em;
  font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, monospace;
  font-size: 85%;
  background-color: rgb(175 184 193 / 20%);
  border-radius: 3px;
  transition: background-color 0.3s ease;
}

:deep(.ant-typography code:hover) {
  background-color: rgb(175 184 193 / 30%);
}

:deep(.ant-typography pre code) {
  padding: 0;
  background-color: transparent;
}

:deep(.ant-typography blockquote) {
  padding: 0 1em;
  margin: 0.5em 0;
  color: #57606a;
  border-left: 0.25em solid #d0d7de;
  animation: fade-in 0.5s ease 0.3s backwards;
}

:deep(.ant-typography ul),
:deep(.ant-typography ol) {
  padding-left: 2em;
  margin: 0.5em 0;
}

:deep(.ant-typography table) {
  width: 100%;
  margin: 0.5em 0;
  border-collapse: collapse;
  animation: fade-in 0.5s ease;
}

:deep(.ant-typography table th),
:deep(.ant-typography table td) {
  padding: 6px 13px;
  border: 1px solid #d0d7de;
  transition: background-color 0.2s ease;
}

:deep(.ant-typography table tr:hover) {
  background-color: rgb(246 248 250 / 70%) !important;
}

:deep(.ant-typography table tr:nth-child(2n)) {
  background-color: #f6f8fa;
}

:deep(.ant-typography img) {
  box-sizing: border-box;
  max-width: 100%;
  transition: transform 0.3s ease;
}

:deep(.ant-typography img:hover) {
  transform: scale(1.03);
}

/* 历史会话相关样式 */
.history-header {
  margin-bottom: 16px;
}

.new-conversation-btn {
  width: 100%;
  margin-bottom: 16px;
  transition: all 0.3s ease;
}

.new-conversation-btn:hover {
  box-shadow: 0 4px 12px rgb(24 144 255 / 15%);
  transform: translateY(-2px);
}

.history-loading {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  color: #8c8c8c;
}

.empty-history {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 40px 0;
  font-size: 14px;
  color: #8c8c8c;
}

.conversation-list {
  margin-top: 12px;
  animation: fade-in 0.3s ease-in-out;
}

.conversation-item {
  margin-bottom: 8px;
  border-radius: 6px;
  transition: all 0.3s ease;
}

.conversation-item:hover {
  background-color: #f0f0f0;
  box-shadow: 0 2px 8px rgb(0 0 0 / 10%);
  transform: translateY(-2px);
}

.active-conversation {
  background-color: #e6f7ff !important;
  border-left: 3px solid #1890ff !important;
}

.history-item {
  width: 100%;
  padding: 8px;
  cursor: pointer;
  transition: all 0.3s ease;
}

.history-item-title {
  overflow: hidden;
  font-size: 14px;
  font-weight: 500;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.history-item-time {
  margin-top: 4px;
  font-size: 12px;
  color: #8c8c8c;
}

/* 添加历史按钮样式 */
.history-button {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  margin-left: 30px;
  font-size: 18px;
  border-radius: 50%;
  transition: all 0.3s ease;
}

.history-button:hover {
  background: rgb(0 0 0 / 5%);
  transform: rotate(30deg);
}

/* 添加模式按钮样式 */
.mode-button {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 32px;
  padding: 0 12px;
  margin: 0 4px;
  font-size: 14px;
  border: 1px solid #d0d7de;
  border-radius: 16px;
  transition: all 0.3s ease;
}

.mode-button:hover {
  color: #1890ff;
  background: rgb(0 0 0 / 5%);
  transform: translateY(-2px);
}

.mode-active {
  color: #1890ff;
  background-color: #e6f7ff;
}

.mode-active:hover {
  background-color: #bae7ff;
}

/* 添加模型选择器样式 */
.model-select {
  flex-shrink: 0;
  min-width: 140px;
  margin: 0 8px;
}

/* 禁止元素收缩 */
.no-shrink {
  flex-shrink: 0;
}

/* 添加消息底部按钮样式 */
.message-footer-buttons {
  width: 100%;
  margin-top: 8px;
  opacity: 0;
  transition: opacity 0.3s ease;
}

:deep(.aiam-bubble-wrapper:hover) .message-footer-buttons {
  opacity: 1;
}

.footer-button {
  color: #8c8c8c;
  transition: all 0.3s ease;
}

.footer-button:hover {
  color: #1890ff;
  background-color: rgb(24 144 255 / 10%);
  transform: scale(1.1);
}

.regenerate-button:hover {
  color: #52c41a;
  background-color: rgb(82 196 26 / 10%);
}

/* 思维链样式 */
:deep(.think-collapse) {
  margin-bottom: 10px;
  background-color: #f5f5f5;
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  animation: think-fade-in 0.4s ease-out;
}

:deep(.think-header) {
  display: flex;
  align-items: center;
  font-weight: 500;
  color: #1890ff;
}

:deep(.think-header::before) {
  margin-right: 5px;
  content: "🧠";
}

:deep(.think-content) {
  padding: 10px;
  font-size: 0.95em;
  color: #595959;
  background-color: #fafafa;
  border-left: 3px solid #1890ff;
  border-radius: 4px;
}

:deep(
  .ant-collapse-ghost
    > .ant-collapse-item
    > .ant-collapse-content
    > .ant-collapse-content-box
) {
  padding: 0 8px 8px;
}

/* 添加PC端自定义侧边栏样式 */
.pc-sidebar {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 1000;
  width: 300px;
  height: 100%;
  padding: 16px;
  overflow-y: auto;
  background-color: #fff;
  border-right: 1px solid #f0f0f0;
  box-shadow: 2px 0 8px rgb(0 0 0 / 10%);
  transition: all 0.3s cubic-bezier(0.23, 1, 0.32, 1);
}

.pc-sidebar-hidden {
  box-shadow: none;
  transform: translateX(-100%);
}

.pc-sidebar-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-bottom: 16px;
  margin-bottom: 16px;
  border-bottom: 1px solid #f0f0f0;
}

.pc-sidebar-title {
  font-size: 16px;
  font-weight: 500;
}

.pc-sidebar-close {
  margin-right: -8px;
  opacity: 0.6;
  transition: all 0.3s;
}

.pc-sidebar-close:hover {
  opacity: 1;
  transform: rotate(90deg);
}

/* 为PC端内容区添加样式 */
.pc-content {
  width: calc(100% - 300px);
  margin-left: 300px; /* 与侧边栏宽度一致 */
  transition: margin 0.3s cubic-bezier(0.23, 1, 0.32, 1);
}

/* PC端模型选择器和输入框宽度自适应 */
.pc-sender .model-selector {
  width: 100%;
}

.pc-sender .input-container {
  width: 100%;
}

/* 添加Welcome图标相关样式 */
.welcome-icon-wrapper {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 50px;
  height: 50px;
  overflow: hidden;
}

.welcome-icon {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* 添加文件预览样式 */
.preview-content {
  height: calc(100vh - 120px);
  padding: 16px;
  overflow-y: auto;
  background-color: #fafafa;
  border-radius: 8px;
}

.preview-text {
  padding: 16px;
  font-size: 14px;
  line-height: 1.6;
  word-wrap: break-word;
  white-space: pre-wrap;
  background-color: #fff;
  border: 1px solid #f0f0f0;
  border-radius: 8px;
}

.preview-excel {
  padding: 16px;
  margin: 0;
  font-family: monospace;
  font-size: 13px;
  line-height: 1.5;
  word-wrap: break-word;
  white-space: pre-wrap;
  background-color: #fff;
  border: 1px solid #f0f0f0;
  border-radius: 8px;
}

/* 修改文件卡片样式以适应预览按钮 */
:deep(.ant-upload-list-item-card-actions) {
  display: flex;
  gap: 8px;
  align-items: center;
}

:deep(.ant-btn-link) {
  padding: 0 4px;
  color: #1890ff;
}

:deep(.ant-btn-link:hover) {
  color: #40a9ff;
  background: transparent;
}

/* 添加预览抽屉过渡动画 */
.preview-drawer-enter-active,
.preview-drawer-leave-active {
  transition: transform 0.3s ease-in-out;
}

.preview-drawer-enter-from,
.preview-drawer-leave-to {
  transform: translateX(100%);
}
</style>
